package com.bz.common;

import java.util.Enumeration;
import java.util.LinkedHashMap;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;

@Aspect
@Component
@Slf4j
public class LogAspect {

    // 指定切入点路径
    @Pointcut("execution(public * com.bz.controller.*.*(..))")
    public void webLogPointcut() {}

    /**
     * 环绕
     * 
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("webLogPointcut()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        long end = System.currentTimeMillis();
        long duration = end - start;

        // 开始打印请求日志
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String url = request.getRequestURI();
        // LinkedHashMap<String, String> headermap = new LinkedHashMap<>();
        // Enumeration<String> header = request.getHeaderNames();
        // if (null != header) {
        // while (header.hasMoreElements()) {
        // String n = header.nextElement();
        // String v = request.getHeader(n);
        // headermap.put(n, v);
        // }
        // }

        LinkedHashMap<String, String> parammap = new LinkedHashMap<>();
        Enumeration<String> param = request.getParameterNames();
        if (null != param) {
            while (param.hasMoreElements()) {
                String n = param.nextElement();
                String v = request.getParameter(n);
                parammap.put(n, v);
            }
        }

        String msg = "请求URL:" +
                     url +
                     ",param:" +
                     JSON.toJSONString(parammap) +
                     ",body:" +
                     JSON.toJSONString(proceedingJoinPoint.getArgs()) +
                     ",res:" +
                     JSON.toJSONString(result) +
                     ",duration:" +
                     duration;
        LogUtils.info(log, msg);

        // 大于5秒，打印告警日志
        if (duration > 5 * 1000) {
            LogUtils.warn(log, msg);
        }
        return result;
    }

}
